﻿Imports System.Drawing.Drawing2D
Imports System.Drawing
Public Class frm_SettingList
    Dim ButtonMode As Boolean = False
    Dim mBorderColor As Color = Color.FromArgb(230, 0, 147, 209)
    Dim mBackColor As Color = Color.FromArgb(200, 255, 255, 255)
    Dim ItemSelectColor1 As Color = Color.FromArgb(62, 150, 215)
    Dim ItemSelectColor2 As Color = Color.FromArgb(51, 138, 202)
    Dim ItemSelectForeColor As Color = Color.White
    Dim ItemForeColor As Color = Color.Blue
    Dim ThumbNormalBorder As Color = Color.Black ' Color.FromArgb(230, 230, 230)
    Dim ThumBNormalColor1 As Color = Color.FromArgb(246, 244, 239)
    Dim ThumBNormalColor2 As Color = Color.FromArgb(238, 234, 227)
    Dim ThumBNormalColor3 As Color = Color.FromArgb(228, 224, 213)
    Dim ThumBNormalColor4 As Color = Color.FromArgb(216, 213, 198)
    Dim ThumBNormalColor5 As Color = Color.FromArgb(246, 244, 239)
    Dim ThumbHoverBorder As Color = Color.FromArgb(180, 180, 180)
    Dim ThumBHoverColor1 As Color = Color.FromArgb(236, 234, 229)
    Dim ThumBHoverColor2 As Color = Color.FromArgb(228, 224, 217)
    Dim ThumBHoverColor3 As Color = Color.FromArgb(218, 214, 203)
    Dim ThumBHoverColor4 As Color = Color.FromArgb(206, 203, 188)
    Dim ThumBHoverColor5 As Color = Color.FromArgb(236, 234, 229)
    Dim ThumbDownBorder As Color = Color.FromArgb(140, 140, 140)
    Dim ThumBDownColor1 As Color = Color.FromArgb(206, 204, 199)
    Dim ThumBDownColor2 As Color = Color.FromArgb(188, 184, 177)
    Dim ThumBDownColor3 As Color = Color.FromArgb(178, 174, 163)
    Dim ThumBDownColor4 As Color = Color.FromArgb(166, 163, 148)
    Dim ThumBDownColor5 As Color = Color.FromArgb(196, 194, 189)
    Dim ThumbBorder As Color = Color.FromArgb(100, 100, 100)
    Dim thumbBackColor As Color = Color.FromArgb(160, 160, 160)
    Dim MouseX As Integer, MouseY As Integer, DownEvent As Boolean = False, ButtonDownEvent As Boolean = False, OverB As Boolean = False
    Dim ScrollWidth As Integer = 11, MaxValue As Integer, Value As Single, mFirstIndex As Integer = 0
    Const ItemHeight As Integer = 25, EffectHeight As Integer = 5, MinHeight As Integer = 30
    Dim DisplayHeight As Integer, DisplayImage As Bitmap
    Public Structure ItemStructure
        Dim Text As String
        Dim Tag As Object
    End Structure
    Dim sItem As New List(Of ItemStructure), mSelectedIndex As Integer = 5
    Dim frmSource As Form
#Region "构造函数"
    Public Sub New(ByVal ParentForm As Form1)

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
        ButtonMode = True
        frmSource = ParentForm
    End Sub
#End Region
    Public ReadOnly Property Items() As List(Of ItemStructure)
        Get
            Return sItem
        End Get
    End Property
    Public Sub AddItem(ByVal Text As String, ByVal mTag As Object)
        Dim tmpItem As New ItemStructure
        With tmpItem
            .Text = Text
            .Tag = mTag
        End With
        sItem.Add(tmpItem)
        Dim PageCount As Integer
        PageCount = (Me.Height - 1 - EffectHeight * 2) / ItemHeight
        If sItem.Count > PageCount Then
            ThumbButton.Visible = True
        Else
            ThumbButton.Visible = False
        End If
        MaxValue = sItem.Count - PageCount
        CaculateThumbHeight()
        If sItem.Count - mFirstIndex <= PageCount Then
            DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
        End If
    End Sub

    Private Sub frm_SettingList_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
    End Sub
    Private Sub frm_SettingList_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
        Me.Hide()
    End Sub
    Private Sub frm_SettingList_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
        If mSelectedIndex >= 0 And mSelectedIndex < sItem.Count Then DirectCast(frmSource, Form1).HandleMenuListClick(sItem.Item(mSelectedIndex).Tag)
        Me.Hide()
    End Sub

    Private Sub frm_SettingList_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Me.BackColor = Color.ForestGreen
        'DrawFormButtonMode(ENUMMOUSEEVENT.MOUSENORMAL)
        Dim PageCount As Integer
        PageCount = (Me.Height - 1 - EffectHeight * 2) / ItemHeight
        If sItem.Count > PageCount Then
            ThumbButton.Visible = True
        Else
            ThumbButton.Visible = False
        End If
        Me.Height = ItemHeight * 15 + EffectHeight * 2
        Me.TopMost = True
        Me.Width = 240
        ThumbButton.Left = Me.Width - ThumbButton.Width - 2
        ThumbButton.Top = EffectHeight
        ThumbButton.BackgroundImageLayout = ImageLayout.Center
        ThumbButton.BackgroundImage = DrawThumbButton()
        CaculateThumbHeight()
        DisplayHeight = Me.Height - 40
        DisplayImage = DrawList(ENUMMOUSEEVENT.MOUSENORMAL)
        DrawBP(Me, DisplayImage, 255)
    End Sub
    Protected Overloads Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H80000
            Return cp
        End Get
    End Property
    Private Sub frm_SettingList_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        DownEvent = True
        MouseX = e.X
        MouseY = e.Y
    End Sub

    Private Sub frm_SettingList_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If DownEvent = False Then
            Dim aIndex As Integer
            aIndex = (e.Y - EffectHeight) \ ItemHeight
            If mFirstIndex + aIndex <> mSelectedIndex Then
                mSelectedIndex = mFirstIndex + aIndex
                DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
            End If
        End If
    End Sub

    Private Sub frm_SettingList_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        DownEvent = False
    End Sub
    Private Function DrawList(Optional ByVal MouseEvent As ENUMMOUSEEVENT = ENUMMOUSEEVENT.MOUSENORMAL) As Bitmap
        If Me.Width <= 0 Or Me.Height <= 0 Then Return Nothing
        Try
            Dim img As New Bitmap(Me.Width - 1, Me.Height - 1)
            Dim g As Graphics = Graphics.FromImage(img)
            Dim PageCount As Integer, ListCount As Integer
            PageCount = (img.Height - EffectHeight * 2) / ItemHeight
            ListCount = sItem.Count
            g.SmoothingMode = SmoothingMode.HighQuality
            Using BorderPen As New Pen(mBorderColor, 1)
                Dim BackPath As New GraphicsPath(FillMode.Alternate)
                Dim BackBrush As New SolidBrush(mBackColor)
                BackPath = CreateRoundPath(New Rectangle(0, 0, img.Width - 1, img.Height - 1), 3)
                g.FillPath(BackBrush, BackPath)
                g.DrawPath(BorderPen, BackPath)
                BackPath.Dispose()
                If ListCount > PageCount Then
                    ScrollWidth = 11
                Else
                    ScrollWidth = 5
                End If
                If ListCount > 0 Then
                    Dim TextBrush As New SolidBrush(ItemForeColor)
                    Dim SelectBrush As New SolidBrush(ItemSelectForeColor)
                    Dim StrFormat As New StringFormat
                    StrFormat.LineAlignment = StringAlignment.Center
                    StrFormat.Alignment = StringAlignment.Near
                    StrFormat.FormatFlags = StringFormatFlags.NoWrap
                    For i = 0 To PageCount
                        If i + mFirstIndex < ListCount And i + mFirstIndex >= 0 Then
                            Dim tmpRect As Rectangle = New Rectangle(2, EffectHeight + i * ItemHeight, img.Width - ScrollWidth, ItemHeight)
                            Dim TextArea As Rectangle = tmpRect
                            TextArea.X = TextArea.Left + 4
                            TextArea.Width = TextArea.Width - 4
                            If mSelectedIndex = i + mFirstIndex Then
                                Dim ItemBrush As New LinearGradientBrush(tmpRect, ItemSelectColor1, ItemSelectColor2, LinearGradientMode.Vertical)
                                g.FillRectangle(ItemBrush, tmpRect)
                                g.DrawString(sItem(i + mFirstIndex).Text, Me.Font, SelectBrush, TextArea, StrFormat)
                            Else
                                g.DrawString(sItem(i + mFirstIndex).Text, Me.Font, TextBrush, TextArea, StrFormat)
                            End If
                        Else
                            Exit For
                        End If
                    Next
                    SelectBrush.Dispose()
                    TextBrush.Dispose()
                    StrFormat.Dispose()
                End If
                If ListCount > PageCount Then
                    Using thumbBrush As SolidBrush = New SolidBrush(thumbBackColor)
                        Dim ThumbBorderPath As GraphicsPath = CreateRoundPath(New Rectangle(img.Width - ThumbButton.Width - 1.5, EffectHeight, ThumbButton.Width, img.Height - EffectHeight * 2 - 1), (ThumbButton.Width - 1) / 2)
                        g.FillPath(thumbBrush, ThumbBorderPath)
                        g.DrawPath(New Pen(ThumbBorder), ThumbBorderPath)
                    End Using
                End If
                If ThumbButton.BackgroundImage IsNot Nothing And ThumbButton.Visible = True Then
                    g.DrawImage(ThumbButton.BackgroundImage, New Rectangle(ThumbButton.Left, ThumbButton.Top, ThumbButton.BackgroundImage.Width, ThumbButton.BackgroundImage.Height), New Rectangle(0, 0, ThumbButton.BackgroundImage.Width, ThumbButton.BackgroundImage.Height), GraphicsUnit.Pixel)
                End If
            End Using
            g.Dispose()
            Return img
        Catch
            Return Nothing
        End Try
    End Function
    Private Function DrawThumbButton(Optional ByVal MouseEvent As ENUMMOUSEEVENT = ENUMMOUSEEVENT.MOUSENORMAL) As Bitmap
        If ThumbButton.Width <= 0 Or ThumbButton.Height <= 0 Then Return Nothing
        Dim Img As New Bitmap(ThumbButton.Width - 1, ThumbButton.Height - 1)
        Dim g As Graphics = Graphics.FromImage(Img)
        g.SmoothingMode = SmoothingMode.HighQuality
        Dim gPath As New GraphicsPath(FillMode.Alternate)
        Dim BarColor1 As Color, BarColor2 As Color, BarColor3 As Color, BarColor4 As Color, BarColor5 As Color, BarBorder As Color
        Select Case MouseEvent
            Case ENUMMOUSEEVENT.MOUSENORMAL
                BarBorder = ThumbNormalBorder
                BarColor1 = ThumBNormalColor1
                BarColor2 = ThumBNormalColor2
                BarColor3 = ThumBNormalColor3
                BarColor4 = ThumBNormalColor4
                BarColor5 = ThumBNormalColor5
            Case ENUMMOUSEEVENT.MOUSEHOVER
                BarBorder = ThumbHoverBorder
                BarColor1 = ThumBHoverColor1
                BarColor2 = ThumBHoverColor2
                BarColor3 = ThumBHoverColor3
                BarColor4 = ThumBHoverColor4
                BarColor5 = ThumBHoverColor5
            Case ENUMMOUSEEVENT.MOUSEDOWN
                BarBorder = ThumbDownBorder
                BarColor1 = ThumBDownColor1
                BarColor2 = ThumBDownColor2
                BarColor3 = ThumBDownColor3
                BarColor4 = ThumBDownColor4
                BarColor5 = ThumBDownColor5
        End Select
        Dim Brush1 As New LinearGradientBrush(New Rectangle(0, 0, Img.Width, Img.Height), BarColor1, BarColor2, LinearGradientMode.Horizontal)
        Dim ColorB As New ColorBlend
        ColorB.Colors = New Color() {BarColor1, BarColor2, BarColor3, BarColor4, BarColor5}
        ColorB.Positions = New Single() {0 / 4.0F, 1 / 4.0F, 2 / 4.0F, 3 / 4.0F, 4 / 4.0F}
        gPath = CreateRoundPath(New Rectangle(0, 0, Img.Width - 1, Img.Height - 1), Img.Width / 2)
        Brush1.InterpolationColors = ColorB
        g.FillPath(Brush1, gPath)
        g.DrawPath(New Pen(ThumbNormalBorder), gPath)
        Brush1.Dispose()
        gPath.Dispose()
        g.Dispose()
        Return Img
    End Function
    Public Sub Remove(ByVal Text As String)
        Dim a As Integer = -1
        For i = sItem.Count - 1 To 0 Step -1
            If Text.ToLower = sItem.Item(i).Text.ToLower Then
                sItem.RemoveAt(i)
            End If
        Next
        CaculateMaxValue()
        DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
    End Sub
    Public Sub ModifyName(ByVal Text As String, ByVal Value As String)
        For i = 0 To sItem.Count - 1
            If Text.ToLower = sItem.Item(i).Text.ToLower Then
                Dim tmpValue As ItemStructure = sItem.Item(i)
                tmpValue.Text = Value
                sItem.Item(i) = tmpValue
            End If
        Next
        DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
    End Sub
    Private Sub ThumbButton_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ThumbButton.MouseDown
        OverB = False
        ButtonDownEvent = True
        MouseY = e.Y '- ThumbButton.Top
        ThumbButton.BackgroundImage = DrawThumbButton(ENUMMOUSEEVENT.MOUSEDOWN) : DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
    End Sub

    Private Sub ThumbButton_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ThumbButton.MouseLeave
        'DownEvent = False
        If ButtonDownEvent = False Then
            OverB = False
            ThumbButton.BackgroundImage = DrawThumbButton(ENUMMOUSEEVENT.MOUSENORMAL) : DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
        End If
    End Sub
    Private Sub ThumbButton_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ThumbButton.MouseMove
        On Error Resume Next
        If ButtonDownEvent = False And OverB = False Then ThumbButton.BackgroundImage = DrawThumbButton(ENUMMOUSEEVENT.MOUSEHOVER) : DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
        If ButtonDownEvent = True Then
            Dim SetY As Integer = ThumbButton.Top + (e.Y - MouseY)
            If SetY >= EffectHeight And SetY <= Me.Height - EffectHeight - ThumbButton.Height - 1 Then
                ThumbButton.Top = SetY
                Value = (SetY - EffectHeight) / (Me.Height - EffectHeight * 2 - ThumbButton.Height - 1)
                mFirstIndex = Value * MaxValue
                DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
            End If
        End If
    End Sub

    Private Sub ThumbButton_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ThumbButton.MouseUp
        ButtonDownEvent = False
    End Sub

    Private Sub ThumbButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ThumbButton.Click

    End Sub

    Private Sub frm_SettingList_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
        If e.Delta < 0 Then
            MouseWheelData(True)
        Else
            MouseWheelData(False)
        End If
    End Sub

    Private Sub frm_SettingList_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        If Me.Width <= 0 Or Me.Height <= EffectHeight * 2 Then Return
        ThumbButton.Left = Me.Width - ThumbButton.Width - 2
        If sItem.Count >= 15 Then
            Me.Height = ItemHeight * 15 + EffectHeight * 2
        ElseIf sItem.Count > 0 Then
            Me.Height = ItemHeight * sItem.Count + EffectHeight * 2
        ElseIf sItem.Count <= 0 Then
            Me.Height = ItemHeight + EffectHeight * 2
        End If
        Me.Width = 240
        CaculateMaxValue()
        CaculateThumbHeight()
        DrawBP(Me, DrawList(ENUMMOUSEEVENT.MOUSENORMAL), 255)
    End Sub
    Private Sub CaculateMaxValue()
        Dim PageCount As Integer
        PageCount = (Me.Height - 1 - EffectHeight * 2) / ItemHeight
        If sItem.Count > PageCount Then
            ThumbButton.Visible = True
        Else
            ThumbButton.Visible = False
            MaxValue = 1
        End If
        MaxValue = sItem.Count - PageCount
    End Sub
    Private Sub CaculateThumbHeight()
        If MaxValue = 1 Then
            ThumbButton.Height = Me.Height - EffectHeight * 2 - 1
        Else
            Dim PageCount As Integer
            Dim Percent1 As Single
            Dim ResultHeight As Integer
            Try
                PageCount = (Me.Height - 1 - EffectHeight * 2) / ItemHeight
                Percent1 = ((Me.Height - EffectHeight * 2 - 1) / ItemHeight) / (sItem.Count - PageCount) * (2 / 3) '(sItem.Count - PageCount) / sItem.Count * (1 / 3)
                ResultHeight = Percent1 * (Me.Height - EffectHeight * 2 - ThumbButton.Height - 2) '* Math.Sqrt(1 / 3)
                If ResultHeight < MinHeight Then ResultHeight = MinHeight
                ThumbButton.Height = ResultHeight
            Catch ex As Exception
                ResultHeight = MinHeight
            End Try
        End If
    End Sub
    Private Sub MouseWheelData(Optional ByVal PlusData As Boolean = True)
        On Error Resume Next
        If ThumbButton.Visible Then
            Dim PageCount As Integer
            PageCount = (Me.Height - 1 - EffectHeight * 2) / ItemHeight
            If PlusData Then
                If mFirstIndex + 1 < sItem.Count - PageCount + 1 Then
                    mFirstIndex = mFirstIndex + 1
                Else
                    Return
                End If
            Else
                If mFirstIndex - 1 >= 0 Then
                    mFirstIndex = mFirstIndex - 1
                Else
                    Return
                End If
            End If
            ThumbButton.Top = EffectHeight + (mFirstIndex / MaxValue) * (Me.Height - EffectHeight * 2 - ThumbButton.Height - 2)
            DrawBP(Me, DrawList(), 255)
        End If
    End Sub
End Class